package com.wswy.wzcx.module.base

import android.arch.lifecycle.MutableLiveData
import android.graphics.Rect
import android.os.SystemClock
import android.support.annotation.ColorRes
import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
import android.support.v7.widget.DividerItemDecoration
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.SnapHelper
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.che.libcommon.api.ApiOptionalResultObserver
import com.che.libcommon.api.BaseResult
import com.che.libcommon.utils.ToastUtils
import com.che.libcommon.utils.optional.Optional
import com.wswy.wzcx.AppContext
import com.wswy.wzcx.R
import io.reactivex.Single


typealias ErrorCallback = ((BaseResult<*>?) -> Unit)?
typealias SuccessCallback<T> = ((T?) -> Unit)?

typealias Func1 = (()->Unit?)?

class ApiCallback<T> : ApiOptionalResultObserver<T> {


    companion object {
        fun toastErrorMsg(result: BaseResult<*>?) {
            if (result != null && !TextUtils.isEmpty(result.msg)) {
                ToastUtils.showText(result.msg)
            }
        }
    }


    private var successCallback: SuccessCallback<T> = null
    private var errorCallback: ErrorCallback = null
    private var resultLiveData:MutableLiveData<Resource<T>>? = null

    constructor(successCallback: SuccessCallback<T> = null) : this(successCallback, null,null)

    constructor(successCallback: SuccessCallback<T>,
                errorCallback: ErrorCallback,
                resultLiveData:MutableLiveData<Resource<T>>?=null) {
        this.successCallback = successCallback
        this.errorCallback = errorCallback
        this.resultLiveData = resultLiveData
    }

    override fun onStart() {
        super.onStart()
        resultLiveData?.postValue(Resource.loading())
    }

    override fun onApiResult(t: T?) {
        successCallback?.invoke(t)

        resultLiveData?.postValue(Resource.success(t))
    }

    override fun onApiError(result: BaseResult<*>?) {
        errorCallback?.invoke(result)

        resultLiveData?.postValue(Resource.error(result))
    }


}



fun <T> Single<Optional<T>>.onSuccess(successCallback: SuccessCallback<in T>):ApiCallback<T>{
    return subscribeWith(ApiCallback<T>(successCallback))
}

fun <T> Single<Optional<T>>.onResult(successCallback: SuccessCallback<in T>, errorCallback: ErrorCallback):ApiCallback<T>{
    return subscribeWith(ApiCallback<T>(successCallback, errorCallback))
}


fun <T> Single<Optional<T>>.onResult(liveData:MutableLiveData<Resource<T>>?):ApiCallback<T>{
    return subscribeWith(ApiCallback<T>(null, null,liveData))
}

fun <T> MutableIterator<T>.removeFirst(predicate:(T)->Boolean){
    while (hasNext()){
        if (predicate(next())){
            remove()
            break
        }
    }
}



fun RecyclerView.Adapter<out RecyclerView.ViewHolder>.loadLayout(parent: ViewGroup, layoutId:Int) = LayoutInflater.from(parent.context).inflate(layoutId,parent,false)


inline fun View.visible() {
    this.visibility = View.VISIBLE
}

inline fun View.gone() {
    this.visibility = View.GONE
}

inline fun View.invisible() {
    this.visibility = View.INVISIBLE
}

/**
 * RecyclerView 添加分隔线
 */
fun RecyclerView.addDividerLine(){
    addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply {
        ContextCompat.getDrawable(context, R.drawable.list_divider_h)?.let {
            setDrawable(it)
        }
    })
}

/**
 * RecyclerView 每行添加间距
 */
fun RecyclerView.addOffset(topOffset:Int,bottomOffset:Int,middle:Int = 0){
    addItemDecoration(object :RecyclerView.ItemDecoration(){
        override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
            super.getItemOffsets(outRect, view, parent, state)
            val pos = parent.getChildAdapterPosition(view)
            val count = state.itemCount
            when (pos) {
                0 -> {
                    outRect.top = topOffset
                    outRect.bottom = 0
                }
                count-1 -> {
                    outRect.top = middle
                    outRect.bottom = bottomOffset
                }
                else -> {
                    outRect.top = middle
                    outRect.bottom = 0
                }
            }
        }
    })
}

fun RecyclerView.addMargin(leftOffset:Int,rightOffset:Int){
    addItemDecoration(object :RecyclerView.ItemDecoration(){
        override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
            super.getItemOffsets(outRect, view, parent, state)
           outRect.left = leftOffset
            outRect.right = rightOffset
        }
    })
}

fun SnapHelper.getSnapPosition(recyclerView: RecyclerView): Int {
    val layoutManager = recyclerView.layoutManager ?: return RecyclerView.NO_POSITION
    val snapView = findSnapView(layoutManager) ?: return RecyclerView.NO_POSITION
    return layoutManager.getPosition(snapView)
}

fun Fragment.getColor(@ColorRes resColor:Int):Int{
    return ContextCompat.getColor(context?:AppContext.getContext(),resColor)
}

fun View.getColor(@ColorRes resColor:Int):Int{
    return ContextCompat.getColor(context?:AppContext.getContext(),resColor)
}


fun Int.paddingZero():String{
    return if (this >=10) toString() else "0$this"
}

private var lastClick = 0L
fun View.onClick(clickListener: ((View)->Unit)){
    setOnClickListener {

        val curr = SystemClock.uptimeMillis()

        if (curr - lastClick > 500){
            lastClick = curr
            clickListener.invoke(this)
        }
    }
}